import cv2
import numpy as np

FLAG_DEBUG = False
FLAG_DRAW_PAD_LINE = True
FLAG_SAVE_YOLO_IMAGE = False
FLAG_DRAW_PAD_NUM = False

def check_bbox_bounds(image, bbox):
        x1, y1, x2, y2 = bbox
        err_x1, err_y1, err_x2, err_y2 = 0, 0, 0, 0
        if x1 < 0:
            err_x1 = -x1
            x1 = 0
        if y1 < 0:
            err_y1 = -y1
            y1 = 0
        if x2 > image.shape[1]:
            err_x2 = x2-image.shape[1]
            x2 = image.shape[1]
        if y2 > image.shape[0]:
            err_y2 = y2-image.shape[0]
            y2 = image.shape[0]
        bbox = [int(x1), int(y1), int(x2), int(y2)]
        error = [err_x1, err_y1, err_x2, err_y2]
        return bbox , error
    
def is_in_bbox(target_bbox, current_pos):
    mid_x = abs((target_bbox[0] + (target_bbox[2] - target_bbox[0]) / 2) - (current_pos[0] + (current_pos[2] - current_pos[0]) / 2))
    mid_y = abs((target_bbox[1] + (target_bbox[3] - target_bbox[1]) / 2) - (current_pos[1] + (current_pos[3] - current_pos[1]) / 2))
    width = (target_bbox[2] - target_bbox[0]) + (current_pos[2] - current_pos[0])
    height = (target_bbox[3] - target_bbox[1]) + (current_pos[3] - current_pos[1])
    
    if mid_x <= width / 2 and mid_y <= height / 2:
        return True
    else:
        return False
    
def calculate_diagonal_length(rectangle,PixelSizeX, PixelSizeY):
    # print(PixelSizeX,'  ', PixelSizeY)
    width = (rectangle[2] - rectangle[0])*PixelSizeX
    height = (rectangle[3] - rectangle[1])*PixelSizeY
    # print(rectangle[2] - rectangle[0])
    # print(rectangle[3] - rectangle[1])
    # print(width,'  ', height)
    diagonal_length = np.sqrt(width**2 + height**2)
    return diagonal_length

def iou(box0, box1):
    xy_max_x = min(box0[2], box1[2])
    xy_max_y = min(box0[3], box1[3])
    xy_min_x = max(box0[0], box1[0])
    xy_min_y = max(box0[1], box1[1])
    
    inter_x = max(0.0, xy_max_x - xy_min_x)
    inter_y = max(0.0, xy_max_y - xy_min_y)
    inter = inter_x * inter_y
    
    area_0 = (box0[2] - box0[0]) * (box0[3] - box0[1])
    area_1 = (box1[2] - box1[0]) * (box1[3] - box1[1])
    union_area = area_0 + area_1 - inter
    
    return inter, union_area, area_0, area_1

def cal_bbox_area(bbox):
    return (bbox[2] - bbox[0]) * (bbox[3] - bbox[1])  

def check_intersection(box1, box2):
    x1_1, y1_1, x2_1, y2_1 = box1
    x1_2, y1_2, x2_2, y2_2 = box2

    # 判断box1的右下角是否在box2的边界之内
    if ((x1_1 <= x2_2 <= x2_1) and (y1_1 <= y2_2 <= y2_1)) or ((x1_2 <= x2_1 <= x2_2) and (y1_2 <= y2_1 <= y2_2)):
        return True

    return False
    

#计算box1和box2相交的部分Frate
def calculate_intersection(box1, box2):
    x1_1, y1_1, x2_1, y2_1 = box1
    x1_2, y1_2, x2_2, y2_2 = box2
    
    x1_new = max(x1_1, x1_2)
    y1_new = max(y1_1, y1_2)
    x2_new = min(x2_1, x2_2)
    y2_new = min(y2_1, y2_2)
    
    return (x1_new, y1_new, x2_new, y2_new)

def subtract_boxes(box1, box2):
    x1_1, y1_1, x2_1, y2_1 = box1
    x1_2, y1_2, x2_2, y2_2 = box2
    
    x1_new = max(x1_1, x2_2)
    y1_new = max(y1_1, y2_2)
    x2_new = min(x2_1, x1_2)
    y2_new = min(y2_1, y1_2)
    
    if x1_new >= x2_new or y1_new >= y2_new:
        return None  # 没有剩余部分
    else:
        return (x1_new, y1_new, x2_new, y2_new)


#计算图片的平均灰度值
def calculate_average_gray(image, box):
    x1, y1, x2, y2 = box
    cropped_region = image[y1:y2, x1:x2]
    average_gray = np.mean(cropped_region)
    return average_gray


def check_madian_bbox(bbox1, bbox2, distance):
    # 计算两个bbox对角点坐标
    x11, y11, x12, y12 = bbox1[0], bbox1[1], bbox1[2], bbox1[3]
    x21, y21, x22, y22 = bbox2[0], bbox2[1], bbox2[2], bbox2[3]
    
    # 判断bbox1是否在bbox2内
    if x21 <= x11 and y21 <= y11 and x22 >= x12 and y22 >= y12:
        
        # 计算bbox1边缘距bbox2的距离
        dx1 = x11 - x21
        dy1 = y11 - y21
        dx2 = x22 - x12 
        dy2 = y22 - y12
        
        # 距离都为1则满足要求
        if dx1 < distance or dy1 < distance or dx2 < distance or dy2 < distance:
            return True
        
    return False


# def check_intersection(box1, box2,rate):
    
#     # 计算每个box的面积
#     area1 = (box1[2] - box1[0]) * (box1[3] - box1[1])
#     area2 = (box2[2] - box2[0]) * (box2[3] - box2[1])
    
#     # 计算相交区域的坐标
#     x1 = max(box1[0], box2[0])
#     y1 = max(box1[1], box2[1]) 
#     x2 = min(box1[2], box2[2])
#     y2 = min(box1[3], box2[3])
    
#     # 计算相交面积
#     inter_area = max(0, x2 - x1) * max(0, y2 - y1)
    
#     # 判断相交面积是否超过box1面积的rate
#     if inter_area / area1 >= rate and inter_area / area1 < 1:
#         return True
#     else:
#         return False
    
def boxes_intersection(box1, box2):
    x1, y1, x2, y2 = int(box1[0]), int(box1[1]), int(box1[2]), int(box1[3])
    x3, y3, x4, y4 = int(box2[0]), int(box2[1]), int(box2[2]), int(box2[3])

    # 判断x坐标是否重叠
    x_overlap = (x1 < x4) and (x3 < x2) 
    
    # 判断y坐标是否重叠
    y_overlap = (y1 < y4) and (y3 < y2)

    # 如果两者都重叠,则两个box相交
    if x_overlap and y_overlap:
        return True
    
    return False

#计算方差
def cal_var(input_list):
    min_variance = float('inf')
    differences = []
    for value in input_list:
        difference = 0
        for x in input_list:
            temp = abs(value - x)**2
            difference = temp + difference
        differences.append(difference)  
    min_differences = min(differences)
    min_index = differences.index(min_differences)
    min_variance_value = input_list[min_index]
    return min_variance_value
        


#根据传入的list将list分成齐平的多个list
def split_col_pad_list(input_boxes_list):
    result_lists = []
    sorted_boxes = sorted(input_boxes_list, key=lambda x: x[0])
    # for sorted_box in sorted_boxes:
    #     print("sorted_box",sorted_box)
    current_group = []
    for coord in sorted_boxes:
        # print("coord",coord)
        if not current_group:
            current_group.append(coord)
        else:
            last_coord = current_group[-1]
            if abs(coord[0] - last_coord[0]) < 3:
                current_group.append(coord)
            else:
                result_lists.append(current_group)
                current_group = [coord]
    if current_group:
        result_lists.append(current_group)
    #对每个list进行处理，将长宽相差较大的box分离出来
    #与第一个box比较长宽
    inconsistent_boxes = []
    for result_list in result_lists:
        
        local_inconsistent = []
        width = result_list[0][2] - result_list[0][0]
        height = result_list[0][3] - result_list[0][1]
        
        for box in result_list[1:]:
            w = box[2] - box[0]
            h = box[3] - box[1]
            if abs(w - width) > 10 or abs(h - height) > 10:
                local_inconsistent.append(box)
        for box in local_inconsistent:
            result_list.remove(box)
        inconsistent_boxes.extend(local_inconsistent)
    if len(inconsistent_boxes) > 0:
        for box in inconsistent_boxes:
            result_lists.append([box]) 
    return result_lists

#根据传入的lists计算坐标的方差
def cal_col_var(input_boxes_lists):
    for input_boxes_list in input_boxes_lists:
        x0_values = [coord[0] for coord in input_boxes_list]
        x1_values = [coord[2] for coord in input_boxes_list]
        
        #计算方差
        x0_var = cal_var(x0_values)
        x1_var = cal_var(x1_values)
        
        #将所有的坐标都设置为方差最小的坐标
        for coord in input_boxes_list:
            coord[0] = x0_var
            coord[2] = x1_var
    return input_boxes_lists


#根据传入的list将list分成齐平的多个list
def split_row_pad_list(input_boxes_list):
    result_lists = []
    sorted_boxes = sorted(input_boxes_list, key=lambda x: x[1])
    current_group = []
    for coord in sorted_boxes:
        if not current_group:
            current_group.append(coord)
        else:
            last_coord = current_group[-1]
            if abs(coord[1] - last_coord[1]) < 3:
                current_group.append(coord)
            else:
                result_lists.append(current_group)
                current_group = [coord]
    if current_group:
        result_lists.append(current_group)
    #对每个list进行处理，将长宽相差较大的box分离出来
    inconsistent_boxes = []
    for result_list in result_lists:
        
        local_inconsistent = []
        width = result_list[0][2] - result_list[0][0]
        height = result_list[0][3] - result_list[0][1]
        
        for box in result_list[1:]:
            w = box[2] - box[0]
            h = box[3] - box[1]
            if abs(w - width) > 10 or abs(h - height) > 10:
                # print("box",box)
                local_inconsistent.append(box)
        for box in local_inconsistent:
            result_list.remove(box)
        
        inconsistent_boxes.extend(local_inconsistent)
    if len(inconsistent_boxes) > 0:
        for box in inconsistent_boxes:
            result_lists.append([box])
    return result_lists

#根据传入的lists计算坐标的方差
def cal_row_var(input_boxes_lists):
    for input_boxes_list in input_boxes_lists:
        y0_values = [coord[1] for coord in input_boxes_list]
        y1_values = [coord[3] for coord in input_boxes_list]
        
        #计算方差
        y0_var = cal_var(y0_values)
        y1_var = cal_var(y1_values)
        
        #将所有的坐标都设置为方差最小的坐标
        for coord in input_boxes_list:
            coord[1] = y0_var
            coord[3] = y1_var
    return input_boxes_lists

def add_pad_edges(image_ch3, bbox):
    up_line_value = bbox[1]
    down_line_value = bbox[3]
    left_line_value = bbox[0]   
    right_line_value = bbox[2]
    if down_line_value-up_line_value<15 or right_line_value-left_line_value<15:
        return bbox
    image = cv2.cvtColor(image_ch3, cv2.COLOR_BGR2GRAY)
    # print("up_line_value",up_line_value,"down_line_value",down_line_value,"left_line_value",left_line_value,"right_line_value",right_line_value)
    roi = image[up_line_value+6:down_line_value-6, left_line_value+6:right_line_value-6]
    # cv2.imwrite("test.jpg",roi)
    sorted_values = np.sort(roi.flatten())[::-1]

    top_percentile = 70
    num_pixels = int((top_percentile / 100) * sorted_values.size)
    selected_values = sorted_values[:num_pixels]

    roi_average_gray_value = np.mean(selected_values)
    #print("roi_average_gray_value", roi_average_gray_value)

    roi = image[up_line_value:down_line_value, left_line_value:right_line_value]
    sorted_values = np.sort(roi.flatten())

    top_percentile = 20
    num_pixels = int((top_percentile / 100) * sorted_values.size)
    selected_values = sorted_values[:num_pixels]

    roi_dark_average_gray_value = np.mean(selected_values)
    #print("roi_dark_average_gray_value", roi_dark_average_gray_value)


    if roi_average_gray_value > 250:
        lightness_threshold = roi_average_gray_value - 100
    elif roi_average_gray_value < 225:
        lightness_threshold = max(roi_average_gray_value - 100, 120)    
    else:
        lightness_threshold = 125

    if  roi_dark_average_gray_value > 99 :
        lightness_threshold = 130

    darkness_threshold = 100    
    if roi_average_gray_value < 235 and roi_dark_average_gray_value < 100:
        darkness_threshold = 90

    if roi_average_gray_value < 210 and roi_dark_average_gray_value > 105:
        darkness_threshold = 120

    ### set reverse pixel adjust
    reverse_pixel_adjust = 4

    ### adjust up line
    average_gray_value = []
    top_80_average_gray_value = []
    max_index = reverse_pixel_adjust
    for i in range(10):

        start_point = (left_line_value+6, up_line_value+i-reverse_pixel_adjust)
        end_point = (right_line_value-6, up_line_value+i-reverse_pixel_adjust) 

        x1, y1 = start_point
        x2, y2 = end_point
        line_pixels = []
        for x in range(x1, x2 + 1):
            for y in range(y1, y2 + 1):
                line_pixels.append(image[y, x])
        #if np.mean(line_pixels) > lightness_threshold :
            #average_gray_value.append(np.mean(line_pixels))
            #continue
        # print(line_pixels)
        average_gray_value.append(np.mean(line_pixels))

        # # 获取排序后的索引
        # sorted_indices = np.argsort(line_pixels)[::-1]  # 逆序排列

        # # 根据索引对原始数组排序
        # line_pixels_sorted = line_pixels[sorted_indices]
        
        line_pixels_sorted = sorted(line_pixels, reverse=True)
        
        
        top_80_percent = int(len(line_pixels_sorted) * 0.8)
        brightest_pixels = line_pixels_sorted[:top_80_percent]
        top_80_average_gray_value.append(sum(brightest_pixels) / len(brightest_pixels))

        #average_rgb.append(np.mean(np.mean(line_pixels, axis=(0, 1))))

    grad_list = []
    for i in range(len(average_gray_value)-1):
        if average_gray_value[i+1]-average_gray_value[i] < 0:
            grad_list.append(0)
        else:
            grad_list.append(abs(average_gray_value[i+1]-average_gray_value[i]))

    #if len(grad_list) != 0:   
        #max_index = grad_list.index(max(grad_list))

    sorted_indices = sorted(range(len(grad_list)), key=lambda i: grad_list[i], reverse=True)

    for i in range(len(sorted_indices)):
        if any(x < darkness_threshold for x in average_gray_value[(sorted_indices[i]+1):]):
            #print(average_gray_value[((sorted_indices[i]+1)):])
            #print("not the proper line because of other dark lines!")
            continue
        if all(x < 120 for x in average_gray_value[(sorted_indices[i]+1):]):
            #print(average_gray_value[((sorted_indices[i]+1)):])
            #print("not the proper line because of all dark lines or dusts!")
            continue        
        if grad_list[sorted_indices[i]] < 16 and average_gray_value[sorted_indices[i]] < 128:
            #print(grad_list[sorted_indices[i]])
            #print("not the proper line because grad is too less!")
            continue
        if top_80_average_gray_value[sorted_indices[i]] > lightness_threshold and abs(top_80_average_gray_value[sorted_indices[i]]-average_gray_value[sorted_indices[i]]) > 15 :
            # print("not the proper line because of top_80_average_gray_value too bright and this line is special!")
            continue
        if i == 0 and grad_list[sorted_indices[1]] > 40 and abs(sorted_indices[0] - sorted_indices[1]) != 1 and (grad_list[sorted_indices[0]] - grad_list[sorted_indices[1]]) < 3:
            #print("there is another obvious line inside!")
            continue
        if average_gray_value[sorted_indices[i]] < lightness_threshold:
            max_index = sorted_indices[i]
            break

    sorted_list = sorted(average_gray_value, reverse=True)
    top_5_values = sorted_list[:5]
    average = sum(top_5_values) / len(top_5_values)   
    if average < 100 :
        max_index = reverse_pixel_adjust

    #print(average_gray_value)
    #print(grad_list)

    up_line_value = up_line_value + max_index -reverse_pixel_adjust


    ### adjust left line
    average_gray_value = []
    top_80_average_gray_value = []
    max_index = reverse_pixel_adjust
    for i in range(10):

        start_point = (left_line_value+i-reverse_pixel_adjust, up_line_value+6)
        end_point = (left_line_value+i-reverse_pixel_adjust, down_line_value-6)    

        x1, y1 = start_point
        x2, y2 = end_point
        line_pixels = []
        for x in range(x1, x2 + 1):
            for y in range(y1, y2 + 1):
                line_pixels.append(image[y, x])
        #if np.mean(line_pixels) > lightness_threshold :
            #average_gray_value.append(np.mean(line_pixels))
            #continue
        average_gray_value.append(np.mean(line_pixels))

        line_pixels_sorted = sorted(line_pixels, reverse=True)
        top_80_percent = int(len(line_pixels_sorted) * 0.8)
        brightest_pixels = line_pixels_sorted[:top_80_percent]
        top_80_average_gray_value.append(sum(brightest_pixels) / len(brightest_pixels))

        #average_rgb.append(np.mean(np.mean(line_pixels, axis=(0, 1))))

    grad_list = []
    for i in range(len(average_gray_value)-1):
        if average_gray_value[i+1]-average_gray_value[i] < 0:
            grad_list.append(0)
        else:
            grad_list.append(abs(average_gray_value[i+1]-average_gray_value[i]))

    #if len(grad_list) != 0:   
        #max_index = grad_list.index(max(grad_list))

    sorted_indices = sorted(range(len(grad_list)), key=lambda i: grad_list[i], reverse=True)

    for i in range(len(sorted_indices)):
        if any(x < darkness_threshold for x in average_gray_value[(sorted_indices[i]+1):]):
            #print(average_gray_value[((sorted_indices[i]+1)):])
            #print("not the proper line because of other dark lines!")
            continue        
        if all(x < 120 for x in average_gray_value[(sorted_indices[i]+1):]):
            #print(average_gray_value[((sorted_indices[i]+1)):])
            #print("not the proper line because of all dark lines or dusts!")
            continue   
        if grad_list[sorted_indices[i]] < 16 and average_gray_value[sorted_indices[i]] < 128:
            #print(grad_list[sorted_indices[i]])
            #print("not the proper line because grad is too less!")
            continue
        if top_80_average_gray_value[sorted_indices[i]] > lightness_threshold and abs(top_80_average_gray_value[sorted_indices[i]]-average_gray_value[sorted_indices[i]]) > 15 :
            print("not the proper line because of top_80_average_gray_value too bright and this line is special!")
            continue
        if i == 0 and grad_list[sorted_indices[1]] > 40 and abs(sorted_indices[0] - sorted_indices[1]) != 1 and (grad_list[sorted_indices[0]] - grad_list[sorted_indices[1]]) < 3:
            #print("there is another obvious line inside!")
            continue   
        if average_gray_value[sorted_indices[i]] < lightness_threshold:
            max_index = sorted_indices[i]
            break

    sorted_list = sorted(average_gray_value, reverse=True)
    top_5_values = sorted_list[:5]
    average = sum(top_5_values) / len(top_5_values)   
    if average < 100 :
        max_index = reverse_pixel_adjust

    #print(average_gray_value)
    #print(grad_list)
    left_line_value = left_line_value + max_index -reverse_pixel_adjust


    ## adjust down line
    average_gray_value = []
    top_80_average_gray_value = []
    max_index = reverse_pixel_adjust
    for i in range(10):

        start_point = (left_line_value+6, down_line_value-i+reverse_pixel_adjust)
        end_point = (right_line_value-6, down_line_value-i+reverse_pixel_adjust)    

        x1, y1 = start_point
        x2, y2 = end_point
        line_pixels = []
        for x in range(x1, x2 + 1):
            for y in range(y1, y2 + 1):
                line_pixels.append(image[y, x])
        #if np.mean(line_pixels) > lightness_threshold :
            #average_gray_value.append(np.mean(line_pixels))
            #continue
        average_gray_value.append(np.mean(line_pixels))

        line_pixels_sorted = sorted(line_pixels, reverse=True)
        top_80_percent = int(len(line_pixels_sorted) * 0.8)
        brightest_pixels = line_pixels_sorted[:top_80_percent]
        top_80_average_gray_value.append(sum(brightest_pixels) / len(brightest_pixels))

        #average_rgb.append(np.mean(np.mean(line_pixels, axis=(0, 1))))

    grad_list = []
    for i in range(len(average_gray_value)-1):
        if average_gray_value[i+1]-average_gray_value[i] < 0:
            grad_list.append(0)
        else:
            grad_list.append(abs(average_gray_value[i+1]-average_gray_value[i]))

    #if len(grad_list) != 0:   
        #max_index = grad_list.index(max(grad_list))

    sorted_indices = sorted(range(len(grad_list)), key=lambda i: grad_list[i], reverse=True)

    for i in range(len(sorted_indices)):
        if any(x < darkness_threshold for x in average_gray_value[(sorted_indices[i]+1):]):
            #print(average_gray_value[((sorted_indices[i]+1)):])
            #print("not the proper line because of other dark lines!")
            continue
        if all(x < 120 for x in average_gray_value[(sorted_indices[i]+1):]):
            #print(average_gray_value[((sorted_indices[i]+1)):])
            #print("not the proper line because of all dark lines or dusts!")
            continue
        if grad_list[sorted_indices[i]] < 16 and average_gray_value[sorted_indices[i]] < 128:
            #print(grad_list[sorted_indices[i]])
            #print("not the proper line because grad is too less!")
            continue 
        if top_80_average_gray_value[sorted_indices[i]] > lightness_threshold and abs(top_80_average_gray_value[sorted_indices[i]]-average_gray_value[sorted_indices[i]]) > 15 :
            #print("not the proper line because of top_80_average_gray_value too bright and this line is special!")
            continue
        if i == 0 and grad_list[sorted_indices[1]] > 40 and abs(sorted_indices[0] - sorted_indices[1]) != 1 and (grad_list[sorted_indices[0]] - grad_list[sorted_indices[1]]) < 3:
            #print("there is another obvious line inside!")
            continue    
        if average_gray_value[sorted_indices[i]] < lightness_threshold:
            max_index = sorted_indices[i]
            break

    sorted_list = sorted(average_gray_value, reverse=True)
    top_5_values = sorted_list[:5]
    average = sum(top_5_values) / len(top_5_values)   
    if average < 100 :
        max_index = reverse_pixel_adjust

    #print(average_gray_value)
    #print(grad_list)

    down_line_value = down_line_value - max_index + reverse_pixel_adjust


    ### adjust right line
    average_gray_value = []
    top_80_average_gray_value = []
    max_index = reverse_pixel_adjust
    #print(right_line_value)
    for i in range(10):

        start_point = (right_line_value-i+reverse_pixel_adjust, up_line_value+6)
        end_point = (right_line_value-i+reverse_pixel_adjust, down_line_value-6)    

        x1, y1 = start_point
        x2, y2 = end_point
        line_pixels = []
        for x in range(x1, x2 + 1):
            for y in range(y1, y2 + 1):
                line_pixels.append(image[y, x])

        #if np.mean(line_pixels) > lightness_threshold :
            #average_gray_value.append(np.mean(line_pixels))
            #continue
        average_gray_value.append(np.mean(line_pixels))

        line_pixels_sorted = sorted(line_pixels, reverse=True)
        top_80_percent = int(len(line_pixels_sorted) * 0.8)
        brightest_pixels = line_pixels_sorted[:top_80_percent]
        top_80_average_gray_value.append(sum(brightest_pixels) / len(brightest_pixels))

        #average_rgb.append(np.mean(np.mean(line_pixels, axis=(0, 1))))

    grad_list = []
    for i in range(len(average_gray_value)-1):
        if average_gray_value[i+1]-average_gray_value[i] < 0:
            grad_list.append(0)
        else:
            grad_list.append(abs(average_gray_value[i+1]-average_gray_value[i]))

    #if len(grad_list) != 0:   
        #max_index = grad_list.index(max(grad_list))

    sorted_indices = sorted(range(len(grad_list)), key=lambda i: grad_list[i], reverse=True)

    for i in range(len(sorted_indices)):
        if any(x < darkness_threshold for x in average_gray_value[(sorted_indices[i]+1):]):
            #print(average_gray_value[((sorted_indices[i]+1)):])
            #print("not the proper line because of other dark lines!")
            continue
        if all(x < 120 for x in average_gray_value[(sorted_indices[i]+1):]):
            #print(average_gray_value[((sorted_indices[i]+1)):])
            #print("not the proper line because of all dark lines or dusts!")
            continue        
        if grad_list[sorted_indices[i]] < 16 and average_gray_value[sorted_indices[i]] < 128:
            #print(grad_list[sorted_indices[i]])
            #print("not the proper line because grad is too less!")
            continue
        if top_80_average_gray_value[sorted_indices[i]] > lightness_threshold and abs(top_80_average_gray_value[sorted_indices[i]]-average_gray_value[sorted_indices[i]]) > 15 :
            #print("not the proper line because of top_80_average_gray_value too bright and this line is special!")
            continue
        if i == 0 and grad_list[sorted_indices[1]] > 40 and abs(sorted_indices[0] - sorted_indices[1]) != 1 and (grad_list[sorted_indices[0]] - grad_list[sorted_indices[1]]) < 3:
            #print("there is another obvious line inside!")
            continue 
        if average_gray_value[sorted_indices[i]] < lightness_threshold:
            max_index = sorted_indices[i]
            break

    sorted_list = sorted(average_gray_value, reverse=True)
    top_5_values = sorted_list[:5]
    average = sum(top_5_values) / len(top_5_values)   
    if average < 100 :
        max_index = reverse_pixel_adjust

    #print(average_gray_value)
    #print(grad_list)
    right_line_value = right_line_value - max_index +reverse_pixel_adjust
    #print(right_line_value)
    roi = image[up_line_value:down_line_value, left_line_value:right_line_value]

    sorted_values = np.sort(roi.flatten())[::-1]

    top_percentile = 70
    num_pixels = int((top_percentile / 100) * sorted_values.size)
    selected_values = sorted_values[:num_pixels]

    average_gray_value = np.mean(selected_values)
    #print("new average_gray_value", average_gray_value)
    return_box = [left_line_value, up_line_value, right_line_value, down_line_value]
    return return_box

   
